﻿using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace QDSpider.Sogou
{
    /// <summary>
    /// 发送Web远程请求类
    /// </summary>
    public class WebRequestHelper
    {
        public static ICredentials Credentials = null;
        public static CookieContainer Cookie = null;
        public static string Referer = "";
        public static string ContentType = "";
        public static string Host = "";
        public static string UserAgent = "";

        static WebRequestHelper()
        {
            Cookie=new CookieContainer();
        }

        public static void Clear()
        {
            Credentials = null;
            Cookie = null; Referer = ""; ContentType = ""; Host = ""; UserAgent = "";
        }

        public static IList<string> AgentList = new List<string>() {
            "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
            "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
            "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
            "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
            "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
            "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
            "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
            "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
            "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",
            "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6",
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20",
            "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",
        };
        public WebRequestHelper()
        {
            ContentType = string.Empty;
        }
        /// <summary>
        /// 发送Get远程请求，返回UTF-8编码的响应流
        /// </summary>
        /// <param name="url">格式：http://www,03you.com/login.aspx?username=test&pwd=123</param>
        /// <param name="html"></param>
        /// <returns></returns>
        public static string Request(string url)
        {
            var html = "";
            Request(url, "", System.Text.Encoding.UTF8, out html);
            return html;
        }
        
        public static string ReplaceHtml(string s)
        {
            s = s.Replace("&#39;", "'");
            s = s.Replace("&quot;", "\"");
            s = s.Replace("&amp;", "&");
            s = s.Replace("&gt;", ">");
            s = s.Replace("&lt;", "<");
            s = s.Replace("&yen;", "¥");
            s = s.Replace("amp;", "");
            s = s.Replace("&lt;", "<");
            s = s.Replace("&gt;", ">");
            s = s.Replace("&nbsp;", " ");
            s = s.Replace("\\", "");
            return s;
        }
        /// <summary>
        /// 发送POST远程请求，返回UTF-8编码的响应流
        /// </summary>
        /// <param name="url"></param>
        /// <param name="param">post请求参数,格式如：UrlEncode("参数一")=UrlEncode("值一") &UrlEncode("参数二")=UrlEncode("值二")</param>
        /// <param name="html">请求返回值</param>
        /// <returns>错误消息</returns>
        public static void Request(string url, string param, System.Text.Encoding encoding, out string html, string method = "GET")
        {
            HttpWebRequest myRequest = null;
            HttpWebResponse myResponse = null;
            Stream reqStream = null;
            StreamReader sRead = null;
            html = string.Empty;
            var data = System.Text.Encoding.Default.GetBytes(param);
            try
            {
                //构造Web请求
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                    myRequest = WebRequest.Create(url) as HttpWebRequest;
                    //myRequest.ProtocolVersion = HttpVersion.Version10;
                }
                else
                    myRequest = (HttpWebRequest)WebRequest.Create(url);
                if (myRequest != null)
                {
                    myRequest.Method = method;
                    myRequest.KeepAlive = true;
                    myRequest.ContentType = ContentType;
                    myRequest.ContentLength = data.Length;
                    myRequest.Timeout = 10000;
                    myRequest.Referer = Referer;
                    //myRequest.ProtocolVersion = HttpVersion.Version11;
                    myRequest.UserAgent = !string.IsNullOrEmpty(UserAgent) ? UserAgent : AgentList[new Random().Next(0, AgentList.Count - 1)];
                    myRequest.Headers.Add("Accept-Language", "zh-cn");
                    if (Cookie == null)
                        Cookie = new CookieContainer();
                    if (Credentials == null)
                        Credentials = CredentialCache.DefaultCredentials;
                    if (!string.IsNullOrEmpty(Host))
                        myRequest.Host = Host;
                    myRequest.CookieContainer = Cookie;
                    myRequest.KeepAlive = false;
                    myRequest.ServicePoint.Expect100Continue = false;

                    //请求流,发送POST参数
                    if (data.Length > 0)
                    {
                        reqStream = myRequest.GetRequestStream();
                        reqStream.Write(data, 0, data.Length);
                        reqStream.Close();
                    }
                    //响应流
                    myResponse = (HttpWebResponse)myRequest.GetResponse();
                }
                if (myResponse != null) sRead = new StreamReader(myResponse.GetResponseStream(), encoding: encoding);
                if (sRead != null) html = sRead.ReadToEnd();
            }
            catch (Exception ex)
            {
                html = ex.Message;
            }
            finally
            {
                sRead?.Close();

                reqStream?.Close();

                myResponse?.Close();

                myRequest?.Abort();
            }
        }

        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true; //总是接受 
        }
    }
}